home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Graphics Unleashed
/
PC Graphics Unleashed.iso
/
ch21
/
bezier_p.c
next >
Wrap
C/C++ Source or Header
|
1994-08-08
|
3KB
|
157 lines
///////////////////////////////
//
// CODE TO DRAW A BEZIER PATCH
// BEZIER_P.C
//
//////////////////////////////
#include <dos.h>
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
typedef struct {
float x,y;
} Point2D;
void InitGraphics(void);
void WorldToDevice(float wx, float wy, int * dx, int * dy);
void DrawAPoint2D(Point2D p);
void DrawALine(Point2D p1, Point2D p2);
float Bernstein(int c, float u);
float GetValue(int i);
float WxLeft, WxRight, WyTop, WyBottom;
int DyMax, DxMax, DyMin, DxMin;
void main(void)
{
int i,j;
float t,tt, B, step;
Point2D c, cc, cc_old, c_old, pnt, p[4][4];
InitGraphics();
WxLeft = -3;
WxRight = 3;
WyTop = 3;
WyBottom = -3;
DyMin = 0;
DxMin = 0;
DyMax = getmaxy();
DxMax = getmaxy();
setviewport((getmaxx()-getmaxy())/2,0,getmaxx(),getmaxy(),1);
setbkcolor(WHITE);
cleardevice();
setcolor(BLUE);
for(j=0;j<4;j++)
for(i=0;i<4;i++) {
p[i][j].x = GetValue(i)+random(10)*0.1;
p[i][j].y = GetValue(j);
DrawAPoint2D(p[i][j]);
}
step = 20.0;
for(tt=0; tt<=(int)step; tt++) {
for(t=0; t<=(int)step; t++) {
c.x = c.y = 0.0;
cc.x = cc.y = 0.0;
for(j=0;j<4;j++) {
for(i=0;i<4;i++) {
B = Bernstein(i,t/step)*Bernstein(j,tt/step);
c.x += p[i][j].x * B;
c.y += p[i][j].y * B;
B = Bernstein(i,tt/step)*Bernstein(j,t/step);
cc.x += p[i][j].x * B;
cc.y += p[i][j].y * B;
}
}
if(!t) {
c_old = c;
cc_old = cc;
}
else {
DrawALine(c_old,c);
DrawALine(cc_old,cc);
cc_old = cc;
}
}
}
getch();
closegraph();
}
/* ================================================================== */
float GetValue(int i) {
switch(i) {
case 0: return(-1.0);
case 1: return(-0.3);
case 2: return(0.3);
default: return(1.0);
}
}
float Bernstein(int c, float u) {
switch(c) {
case 0: return (pow((1.0-u),3));
case 1: return (3.0 * u * pow((1.0-u),2));
case 2: return (3.0 * pow(u,2) * (1.0-u));
default: return (pow(u,3));
}
}
void WorldToDevice(float wx, float wy, int * dx, int * dy) {
*dx = (WxLeft - wx) * DxMax / (WxLeft - WxRight);
*dy = (WyTop - wy) * DyMax / (WyTop - WyBottom);
}
void DrawAPoint2D(Point2D p) {
int dx, dy;
WorldToDevice(p.x, p.y, &dx, &dy);
rectangle(dx-2,dy-2,dx+2,dy+2);
}
void DrawALine(Point2D p1, Point2D p2) {
int dx1, dy1, dx2, dy2;
WorldToDevice(p1.x, p1.y, &dx1, &dy1);
WorldToDevice(p2.x, p2.y, &dx2, &dy2);
line(dx1,dy1,dx2,dy2);
}
void InitGraphics(void)
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* terminate with an error code */
}
setviewport(0,0,getmaxx(),getmaxy(),1);
}